﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.SYS;
using System.Data.Entity;
using System.Linq.Dynamic;

namespace KPIS.GERP.WCF.ESS
{
    [ServiceContract]
    public interface IMessageService
    {
        [OperationContract]
        int CountUnreadMessage(int empId);

        [OperationContract]
        int CountUnwarnMessage(int empId);

        [OperationContract]
        void WarnMessages(int empId);

        [OperationContract]
        void ReadMessage(int messageId, int empId);

        [OperationContract]
        IEnumerable<Message> SelectMessage(Message criteriaModel, List<string> includeSubObjectString);
    }

    [ServiceErrorBehavior(typeof(ElmahErrorHandler))]
    public class MessageService : IMessageService
    {
        GERPContext db = new GERPContext();

        public int CountUnreadMessage(int empId)
        {
            int count = (from m in db.Messages
                         where m.ToEmpId == empId
                               && m.RecordStatus != RecordStatus.DeletedStatus
                               && m.MessageStatus != MessageWarningStatus.Read
                         select m).Count();
            return count;
        }

        public int CountUnwarnMessage(int empId)
        {
            int count = (from m in db.Messages
                         where m.ToEmpId == empId
                               && m.RecordStatus != RecordStatus.DeletedStatus
                               && m.MessageStatus != MessageWarningStatus.Unwarn
                         select m).Count();
            return count;
        }

        public void WarnMessages(int empId)
        {
            using (var db2 = new GERPContext(true))
            {
                var allMessageUnwarn = db2.Messages.Where(m => m.ToEmpId == empId
                                                              && m.RecordStatus != RecordStatus.DeletedStatus
                                                              && m.MessageStatus == MessageWarningStatus.Unwarn);
                foreach (var messageUnwarn in allMessageUnwarn)
                {
                    messageUnwarn.MessageStatus = MessageWarningStatus.Unread;
                    messageUnwarn.UpdatedBy = empId;
                    messageUnwarn.UpdatedWhen = DateTime.Now;
                }

                db2.SaveChanges();
            }
        }

        public void ReadMessage(int messageId, int empId)
        {
            using (var db2 = new GERPContext(true))
            {
                var allMessageUnwarn = db2.Messages.Where(m => m.MessageId == messageId);
                foreach (var messageUnwarn in allMessageUnwarn)
                {
                    messageUnwarn.MessageStatus = MessageWarningStatus.Read;
                    messageUnwarn.UpdatedBy = empId;
                    messageUnwarn.UpdatedWhen = DateTime.Now;
                }
                db2.SaveChanges();
            }
        }

        public IEnumerable<Message> SelectMessage(Message criteriaModel, List<string> includeSubObjectString)
        {
            try
            {
                using (var context = new GERPContext(false))
                { 
                    IQueryable<Message> query = context.Messages;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    query = query.Include(o => o.ApprovalTaskDtl.ApprovalTask.OriginalApproveProcess.ApproveProcessGroup).Include(o=>o.FromEmployee.JobSite).Include(o=>o.ToEmployee.JobSite);

                    var x = query.ToList();

                    foreach (var message in x)
                    {
                        if(message.ApprovalTaskDtl != null && message.ApprovalTaskDtl.ApprovalTask != null)
                        {
                           message.ApprovalTaskDtl.ApprovalTask.ApprovalTaskDtls = new Collection<ApprovalTaskDtl>();
                            if(message.ApprovalTaskDtl.ApprovalTask.CompletedDtl != null)
                            {
                                message.ApprovalTaskDtl.ApprovalTask.CompletedDtl.ApprovalTask = null;
                            }
                        }
                        if(message.ApprovalTaskDtl != null && message.ApprovalTaskDtl.ApprovalTask != null && message.ApprovalTaskDtl.ApprovalTask.OriginalApproveProcess != null && message.ApprovalTaskDtl.ApprovalTask.OriginalApproveProcess.ApproveProcessGroup != null)
                        {
                            message.ApprovalTaskDtl.ApprovalTask.OriginalApproveProcess.ApproveProcessGroup.ApproveProcesses = new Collection<ApproveProcess>();
                        } 
                    }

                    return x;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
